package track2.bayes;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;

import track2.context.Config;
import track2.data.DescriptionToken;
import track2.data.PurchaseKeywordToken;
import track2.data.QueryToken;
import track2.data.TitleToken;
import track2.data.UserProfile;
import track2.result.Result;

/**
 * Doing test work for {@link TrainClassifier}
 * 
 * @author yijia, lingjuan
 * 
 */
public class TestClassifier {

	/**
	 * Test function for naive bayes
	 * 
	 * @return Result
	 */
	static AmazonS3 s3;
	public static Result test(NaiveBayesFeatures feature) throws IOException {
		System.out.println("Test begins....");
		Result result = new Result();
		result.naiveBayesResultScore = new double[Config.testInstanceNum];
		int index = 0;
		AWSCredentials credentials = new PropertiesCredentials(
				TestClassifier.class.getResourceAsStream("AwsCredentials.properties"));
		s3 = new AmazonS3Client(credentials);
		try {
			S3Object object = s3.getObject(new GetObjectRequest("bigmlplj",
					"track2/test.txt"));
			BufferedReader br = new BufferedReader(new InputStreamReader(
					object.getObjectContent()));
//			BufferedReader br = new BufferedReader(new FileReader(
//					Config.testFilePath));
			String line;
			int countline = 0;
			while ((line = br.readLine()) != null) {
				if(countline%100000 == 0){
					System.out.println(countline);
				}
				countline++;
				String[] paras = line.split("\\t");
				int queryID = Integer.parseInt(paras[5]);
				int purchaseID = Integer.parseInt(paras[6]);
				int titleID = Integer.parseInt(paras[7]);
				int descriptionID = Integer.parseInt(paras[8]);
				int userID = Integer.parseInt(paras[9]);

				String query = getToken("Q", queryID);
				String title = getToken("T", titleID);
				String purchase = getToken("P", purchaseID);
				String description = getToken("D", descriptionID);
				String user = getToken("U", userID);

				double[] prob = new double[2];// 0 is for click probability, 1
												// for unclick probability
				// prior probability
				prob[0] += Math.log(feature.click);
				prob[1] += Math.log((1 - feature.click));
				
				getClickProb("Q", query, feature, prob);
				getClickProb("T", title, feature, prob);
				getClickProb("P", purchase, feature, prob);
				getClickProb("D", description, feature, prob);
				getClickProb("U", user, feature, prob);
				
				//1/(1+e^(log(B)-log(A));
				result.naiveBayesResultScore[index] = 1.0/(1.0+Math.exp(prob[1]-prob[0]));
				index++;

			}
			br.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 
	 * @return click probability
	 */
	public static void getClickProb(String flag, String value,
			NaiveBayesFeatures feature,
			double[] prob) {
		String[] tokens = value.split("\\|");
		if (flag.equals("Q")) {// QueryID
			getClick(feature.queryClick, feature.queryNotClick, tokens, prob);
		} else if (flag.equals("T")) {// TitleID
			getClick(feature.titleClick, feature.titleNotClick, tokens, prob);
		} else if (flag.equals("P")) {// PurchaseID
			getClick(feature.purchaseClick, feature.purchaseNotClick,
					tokens, prob);
		} else if (flag.equals("D")) {// DescriptionID
			getClick(feature.descriptionClick,
					feature.descriptionNotClick, tokens, prob);
		} else if (flag.equals("U")) {// UserID
			getClick(feature.ageClick, feature.ageNotClick, tokens, prob);
			getClick(feature.genderClick, feature.genderNotClick,
					tokens, prob);
		}
	}

	private static void getClick(double[] queryClick,
			double[] queryNotClick, String[] tokens, 
			double[] prob) {
		for (int i = 0; i < tokens.length; i++) {
			int token = Integer.parseInt(tokens[i]);
			prob[0] += Math.log(queryClick[token]);
			prob[1] += Math.log(queryNotClick[token]);
		}

	}

	// get tokens
	public static String getToken(String flag, int id) throws IOException {
		String result = null;
		if (flag.equals("Q")) {// QueryID
			result = QueryToken.getInstance().getMap().get(id);
		} else if (flag.equals("T")) {// TitleID
			result = TitleToken.getInstance().getMap().get(id);
		} else if (flag.equals("P")) {// PurchaseID
			result = PurchaseKeywordToken.getInstance().getMap().get(id);
		} else if (flag.equals("D")) {// DescriptionID
			result = DescriptionToken.getInstance().getMap().get(id);
		} else if (flag.equals("U")) {// UserID
			result = UserProfile.getInstance().getMap().get(id);
		}
		return result;
	}
}
